Skip to content

Add self-correction loop: logs, call, and shot commands - #30

Merged
molefrog merged 4 commits into
mainfrom
claude/agent-self-correction-aegbzt
Jul 18, 2026
Merged

Add self-correction loop: logs, call, and shot commands#30
molefrog merged 4 commits into
mainfrom
claude/agent-self-correction-aegbzt

Conversation

@molefrog

@molefrog molefrog commented Jul 7, 2026

Copy link
Copy Markdown
Owner

Implements the three-leg self-correction feedback loop for applets, allowing the agent to detect runtime failures, test server functions, and see what applets actually look like without waiting for user feedback.

Summary

Adds three new CLI commands (moi logs, moi call, moi shot) that close the gap between successful builds and actual runtime behavior. The agent can now:

  • Feel (moi logs) — query an in-memory error journal of applet runtime failures
  • Poke (moi call) — invoke server functions directly through the same worker pool as browser RPC
  • See (moi shot) — render applets to PNG through a live workspace tab

Key Changes

Server-side error journal (server/applet-log.ts)

  • Per-workspace, in-memory ring buffer (100 entries max) tracking applet failures
  • Records five error sources: build, load, render, window, rpc
  • Deduplicates identical errors (same source + attribution + message) by bumping a counter
  • Clears entries when an applet rebuilds successfully (old bundle no longer exists)
  • Entries include timestamp, source, applet attribution, message, optional stack, and occurrence count

CLI commands (server/cli.ts)

  • moi logs [--json] [--clear] — display or clear the error journal
  • moi call <module>/<fn> '[args]' — invoke a server function with JSON arguments, returns devalue-encoded result
  • moi shot widget|view <name> — screenshot an applet at its real grid size (or full panel for views)

Browser-side error reporting (client/lib/applet-log.ts)

  • Catches module load failures, render crashes, and window-level errors
  • Attributes errors to applets by matching stack frames against bundle URLs
  • POSTs errors to POST /api/workspaces/:id/applet-log with per-error cooldown (5s) to prevent storms
  • Always-on reporting: errors are recorded even if the user doesn't immediately report them

Applet screenshot support (client/lib/applet-shot.tsx, server/applet-shot.ts)

  • Mounts applets offscreen in the workspace's themed wrapper (so fonts/colors apply correctly)
  • Waits for mount-time data fetches to settle (configurable, default 1.5s)
  • Rasterizes with modern-screenshot and measures content overflow
  • Returns PNG + render facts (box dimensions, content size) to the CLI
  • Uses relay pattern (same as Scratchpad) to broadcast requests to live tabs

Control port integration (server/control.ts)

  • Refactored sendScratch → generic sendControl to handle multiple request types
  • Added handlers for logs, call, and shot request types
  • moi bundle output now nudges toward moi logs when errors are on record

Type definitions (lib/types.ts)

  • AppletKind'widget' | 'view'
  • AppletLogSource'build' | 'load' | 'render' | 'window' | 'rpc'
  • AppletLogEntry — full journal entry shape with dedup count
  • ShotRequest / ShotResult — screenshot request/response types

Generic relay utility (server/relay.ts)

  • Extracted relay mechanics (pending map, timeout, first-reply-wins) into reusable createRelay<Res>
  • Used by both Scratchpad (scratchpad-relay.ts) and applet shots (applet-shot.ts)

Error boundary updates (client/components/WidgetErrorBoundary.tsx)

  • Now reports render crashes to the applet log
  • Accepts kind (widget/view) and workspaceId for attribution
  • Optional onError callback for callers like applet shots

RPC error recording (server/api.ts)

  • Server-function failures now recorded in the journal with module/function attribution
  • Allows moi call to surface issues before the browser sees them

https://claude.ai/code/session_01M8rSCv39HrkfaH23tceb2q

The agent that builds applets could not tell when they broke: a widget
compiles, then fails to load in the browser, crashes on render, or its
server function throws — and nothing reaches the agent until the user
complains. Close the loop with two legs (spec: docs/self-correction.md):

- moi debug logs — an applet error journal under the new experimental
  `moi debug` command group. A per-workspace, in-memory ring buffer fed
  server-side (RPC failures, build failures) and by the browser (load
  failures, render crashes via the error boundary, window errors
  attributed by bundle-URL stack match, POSTed to /applet-log with a
  hostile-input guard). Identical errors dedup into a count; a
  successful rebuild clears the applet's standing entries; `moi bundle`
  ends with a nudge when errors remain on record.
- moi call-server-fn — invoke one .server.ts function directly. Each
  invocation runs in an EPHEMERAL one-shot worker: spawn, single call,
  kill — fully isolated from the warm pool the widgets use, with the
  same env injection, module loading, timeout, and devalue wire format.
  Args as one JSON array; results render via Bun.inspect with duration.

The moi-workspace skill grows a "Verify your work" section teaching the
loop (bump to 0.6.0), with `moi debug` marked experimental.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M8rSCv39HrkfaH23tceb2q
@molefrog
molefrog force-pushed the claude/agent-self-correction-aegbzt branch from 7f037df to 174ab37 Compare July 17, 2026 09:12
- `moi refresh` — re-fetch widget/view data without rebuilding (use after you mutated data the
widgets read — DB rows, files, external API records — so the displayed values catch up)
- `moi call-server-fn <module>/<fn> '[args]'` — invoke a `.server.ts` function directly
(smoke test; see Verify your work)

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove "see..."

widgets read — DB rows, files, external API records — so the displayed values catch up)
- `moi call-server-fn <module>/<fn> '[args]'` — invoke a `.server.ts` function directly
(smoke test; see Verify your work)
- `moi debug logs` — applet runtime errors on record (experimental; see Verify your work)

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- `moi debug logs` — applet runtime errors on record (experimental; see Verify your work)
- `moi debug logs` — applet runtime errors on record (experimental)

claude added 3 commits July 18, 2026 17:29
Address PR #30 review: drop the "see Verify your work" cross-references
from the CLI list, and rewrite the section (now "Debugging applets") so
call-server-fn and debug logs are offered as feedback channels the agent
can reach for, rather than a mandated verify-every-time checklist. The
ambient signals (bundle footer nudge, always-on browser reporting) carry
the discovery instead.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M8rSCv39HrkfaH23tceb2q
Two upgrades to the window-error half of the applet journal:

- Attribute 'error' events via ErrorEvent.filename first — a structured
  URL with no per-browser stack-format quirks, which also covers throws
  that carry no usable stack (`throw 'string'`). The stack-text scan
  stays as the fallback (handler threw inside vendor code) and as the
  only path for unhandled rejections, which have no filename.
- Close the flood hole: the per-error cooldown keys on the message, so
  an error whose text varies each occurrence (timestamps, ids) bypassed
  it — and the server dedup — turning a tight throw loop into a POST
  storm. A global cap (30 reports/min, silent drops) bounds the total
  regardless of message shape.

The URL matcher is extracted and unit-tested against bare filenames,
Chrome/Firefox stack shapes, and near-miss URLs (vendor, rpc).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M8rSCv39HrkfaH23tceb2q
@molefrog
molefrog merged commit 05cc056 into main Jul 18, 2026
1 check passed
molefrog pushed a commit that referenced this pull request Jul 18, 2026
Address PR #30 review: drop the "see Verify your work" cross-references
from the CLI list, and rewrite the section (now "Debugging applets") so
call-server-fn and debug logs are offered as feedback channels the agent
can reach for, rather than a mandated verify-every-time checklist. The
ambient signals (bundle footer nudge, always-on browser reporting) carry
the discovery instead.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M8rSCv39HrkfaH23tceb2q
@molefrog
molefrog deleted the claude/agent-self-correction-aegbzt branch July 18, 2026 19:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants